package com.sl.ms.web.customer.service.impl;

import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.sl.ms.web.customer.service.WechatService;
import com.sl.transport.common.exception.SLWebException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.Map;

@Service
@Slf4j
public class WechatServiceImpl implements WechatService {
    //微信小程序appid
    @Value("${sl.wechat.appid}")
    private String appid;
    //微信小程序秘钥
    @Value("${sl.wechat.secret}")
    private String secret;

    public static final String LOGIN_URL = "https://api.weixin.qq.com/sns/jscode2session";
    private static final int TIMEOUT = 20000;

    public static final String TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token";
    public static final String PHONE_URL = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=";


    /**
     * 获取openid
     *
     * @param code 登录凭证
     * @return 唯一标识
     * @throws IOException IO异常
     */
    @Override
    public JSONObject getOpenid(String code) throws IOException {
        //1.封装参数
        Map<String, Object> requestParam = MapUtil.<String, Object>builder()
                .put("appid", this.appid)  //小程序appid
                .put("secret", this.secret) //小程序appSecret
                .put("js_code", code) //	登录时获取的 code，可通过wx.login获取
                .put("grant_type", "authorization_code") //授权类型
                .build();
        //2.发送请求
        HttpResponse response = cn.hutool.http.HttpRequest.get(LOGIN_URL)  //设置get请求url
                .form(requestParam)  //设置表单参数
                .timeout(TIMEOUT)  //设置超时时间，20s
                .execute(); //执行请求
        if (response.isOk()) {
            //3.解析响应的结果，如果出现错误抛出异常
            JSONObject jsonObject = JSONUtil.parseObj(response.body());
            if (jsonObject.containsKey("errcode")) {
                throw new SLWebException(jsonObject.toString());
            }
            return jsonObject;
        }
        String errMsg = StrUtil.format("调用微信登录接口出错！ code={}", code);
        throw new SLWebException(errMsg);
    }

    //获取手机号
    @Override
    public String getPhone(String code) throws IOException {
        //1. 获取手机号，需要先获取微信access_token
        String token = this.getToken(code);
        //2.封装参数
        Map<String, Object> requestParam = MapUtil.<String, Object>builder()
                .put("code", code) //手机号获取凭证
                .build();
        //发送请求
//        HttpRequest.post(PHONE_URL+token)


        return null;
    }

    //获取token
    private String getToken(String code){
        //获取Token
        //1.封装参数
        Map<String, Object> requestParam = MapUtil.<String, Object>builder()
                .put("appid", this.appid) //小程序 appId
                .put("secret", this.secret) //小程序 appSecret
                .put("grant_type", "client_credential") //授权类型
                .build();
        //2.发送请求
        HttpResponse response = HttpRequest.get(TOKEN_URL) //设置get请求url
                .form(requestParam)  //设置表单参数
                .timeout(TIMEOUT)  //设置超时时间，20s
                .execute(); //执行请求

        if (response.isOk()){
            //3.解析响应的结果，如果出现错误则抛出异常
            JSONObject jsonObject = JSONUtil.parseObj(response.body());
            if (jsonObject.containsKey("errcode")){
                throw new SLWebException(jsonObject.toString());
            }
            //TODO：未出现错误，缓存token到redis中，不应该每次都获取token
            return jsonObject.getStr("access_token");
        }
        String errMsg = StrUtil.format("调用获取接口调用凭据接口出错！");
        throw new SLWebException(errMsg);
    }

}
